package c2.cross.business.championrace.handler;

import c2.cross.business.championrace.ChampionRaceModule;
import cate.common.util.GameResult;
import cate.game.pvp.championrace.data.ChampionRaceBetRecord;
import cate.game.pvp.championrace.data.ChampionRacePs;
import cate.game.pvp.championrace.data.ChampionRaceRecord;
import cate.game.pvp.championrace.timer.ChampionRaceTimerTask;
import cate.game.pvp.championrace.ChampionRaceSpecUtils;
import easy.java.practice.errorcode.EcResult;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.StringUtils;

import java.util.LinkedList;
import java.util.Objects;

import static cate.game.pvp.championrace.ChampionRaceSpecUtils.*;


public class ChampionRaceTrialSettingHandler extends AbstractChampionRaceSettingHandler{
    @Getter
    @Setter
    private boolean running = false;

    @Getter
    private final LinkedList<ChampionRaceRecord> recordQueue = new LinkedList<>();

    private long currentPowerDiff = Long.MAX_VALUE;
    private ChampionRaceRecord betRecord;

    public ChampionRaceTrialSettingHandler(ChampionRaceModule parent) {
        super(parent);
    }

    @Override
    public boolean runSettingFunction(ChampionRaceTimerTask.Setting setting) {
        boolean canChange = parent.canChangeSpec(setting, ChampionRaceSpecUtils.getTrialFlag(setting));
        if (!canChange) {
            return true;
        }
        if (!isRunning()) {
            setRunning(true);
            recordQueue.addAll(parent.queryRecords(setting.getSpec()));
        }
        boolean result = handleQueuedTask();
        if (result) {
            if (Objects.nonNull(betRecord)) {
                betRecord.setBetRound(true);
                ChampionRacePs psA = parent.findPs(betRecord.getIdA());
                ChampionRacePs psB = parent.findPs(betRecord.getIdB());
                parent.addBetRecordData(ChampionRaceBetRecord.of(betRecord, psA, psB, betRecord.getWinner()));
                betRecord = null;
                currentPowerDiff = Long.MAX_VALUE;
            }
            parent.changeSpec(setting, ChampionRaceSpecUtils.getTrialFlag(setting));
        }
        return result;
    }

    private boolean handleQueuedTask() {
        ChampionRaceRecord recordTask;

        long startMs = System.currentTimeMillis();
        while ((recordTask = recordQueue.poll()) != null) {
            EcResult<Long> r = handleFightTask(recordTask);
            if (r.ok()) {
                if (r.data < currentPowerDiff) {
                    currentPowerDiff = r.data;
                    betRecord = recordTask;
                }
            }
            if (System.currentTimeMillis() - startMs > 500L) {
                break;
            }
        }
        if (recordQueue.isEmpty()) {
            setRunning(false);
        }
        return !isRunning();
    }

    private GameResult<Long> handleFightTask(ChampionRaceRecord recordTask) {
        ChampionRacePs psA = null, psB = null;
        if (StringUtils.hasLength(recordTask.getIdA())) {
            psA = parent.findPs(recordTask.getIdA());
        }
        if (StringUtils.hasLength(recordTask.getIdB())) {
            psB = parent.findPs(recordTask.getIdB());
        }
        return parent.startFight(recordTask, psA, psB);
    }

    @Override
    public boolean isMatch(ChampionRaceTimerTask.Setting setting) {
        return isMatchTrialSimulator(setting);
    }

    @Override
    public void run() {

    }
}
